﻿Namespace DoFactory.GangOfFour.Facade.RealWorld

    ''' <summary>
    ''' MainApp startup class for Real-World
    ''' Facade Design Pattern.
    ''' </summary>
    Public Class MainApp
        ''' <summary>
        ''' Entry point into console application.
        ''' </summary>
        Public Shared Sub Main()

            ' Facade
            Dim mortgage As New Mortgage()

            ' Evaluate mortgage eligibility for customer
            Dim customer As New Customer("Ann McKinsey")

            Dim eligible As Boolean = mortgage.IsEligible(customer, 125000)

            Console.WriteLine(vbLf & customer.Name & " has been " & (If(eligible, "Approved", "Rejected")))

        End Sub

    End Class

    ''' <summary>
    ''' The 'Subsystem ClassA' class
    ''' </summary>
    Class Bank
        Public Function HasSufficientSavings(ByVal c As Customer, ByVal amount As Integer) As Boolean
            Console.WriteLine("Check bank for " & c.Name)
            Return True
        End Function
    End Class

    ''' <summary>
    ''' The 'Subsystem ClassB' class
    ''' </summary>
    Class Credit

        Public Function HasGoodCredit(ByVal c As Customer) As Boolean
            Console.WriteLine("Check credit for " & c.Name)
            Return True
        End Function
    End Class

    ''' <summary>
    ''' The 'Subsystem ClassC' class
    ''' </summary>
    Class Loan

        Public Function HasNoBadLoans(ByVal c As Customer) As Boolean
            Console.WriteLine("Check loans for " & c.Name)
            Return True
        End Function
    End Class

    ''' <summary>
    ''' Customer class
    ''' </summary>
    Class Customer

        Private _name As String

        ' Constructor
        Public Sub New(ByVal name As String)
            Me._name = name
        End Sub

        ' Gets the name
        Public ReadOnly Property Name() As String
            Get
                Return _name
            End Get
        End Property
    End Class

    ''' <summary>
    ''' The 'Facade' class
    ''' </summary>
    Class Mortgage

        Private _bank As New Bank()
        Private _loan As New Loan()
        Private _credit As New Credit()

        Public Function IsEligible(ByVal cust As Customer, ByVal amount As Integer) As Boolean
            Console.WriteLine("{0} applies for {1:C} loan" & vbLf, cust.Name, amount)
            Dim eligible As Boolean = True

            ' Check creditworthyness of applicant
            If Not _bank.HasSufficientSavings(cust, amount) Then
                eligible = False
            ElseIf Not _loan.HasNoBadLoans(cust) Then
                eligible = False
            ElseIf Not _credit.HasGoodCredit(cust) Then
                eligible = False
            End If

            Return eligible
        End Function

    End Class

End Namespace
